package cn.infrabase.core.lang;

import javax.annotation.Nullable;
import java.lang.reflect.Array;

/**
 * @author Weimin Gao
 * @since 1.0.0
 **/
public class ArrayUtils {

    /**
     * <pre>
     * 断言给定的对象是否为数组对象。
     * 例子：
     * assertFalse(ArrayUtils.isArray(""));
     * assertFalse(ArrayUtils.isArray(null));
     * assertFalse(ArrayUtils.isArray("[]"));
     * assertTrue(ArrayUtils.isArray(new String[]{}));
     * </pre>
     *
     * @param obj 给定的对象。
     * @return 真（true）给定的对象是数组对象，如果给定的对象为null时则返回假（false）。
     */
    public static boolean isArray(Object obj) {
        return null != obj && obj.getClass().isArray();
    }

    /**
     * <pre>
     * 断言给定的数组是否为空（数组为null或数组长度为0时）。
     * 例子：
     * assertTrue(ArrayUtils.isEmpty(new String[]{}));
     * assertFalse(ArrayUtils.isEmpty(new String[]{"1"}));
     * </pre>
     *
     * @param <T>   数组元素类型。
     * @param array 数组。
     * @return 真（true）表示给定的数据为空。
     */
    public static <T> boolean isEmpty(@Nullable T[] array) {
        return array == null || array.length == 0;
    }

    /**
     * <pre>
     * 断言给定的对象是否为空。
     * 如果给定的对象为null时则返回真（true）。
     * 如果给定的对象为非数组且不为null时则返回假（false）。
     * 如果给定的对象为数组且长度等于0时返回真（true），否则返回假（false）。
     * 例子：
     * assertFalse(ArrayUtils.isEmpty(""));
     * assertTrue(ArrayUtils.isEmpty((Object)new String[]{}));
     * assertFalse(ArrayUtils.isEmpty((Object)new String[]{"1"}));
     * </pre>
     *
     * @param obj 给定的对象。
     * @return 真（true）表示给定的对象为非空。
     */
    public static boolean isEmpty(Object obj) {
        if (obj != null) {
            if (isArray(obj)) {
                return 0 == Array.getLength(obj);
            }
            return false;
        }
        return true;
    }

    /**
     * <pre>
     * 断言给定的数组是否为非空（数组不为null和数组长度不为0时）。
     * 例子：
     * assertFalse(ArrayUtils.isNotEmpty(new String[]{}));
     * assertTrue(ArrayUtils.isNotEmpty(new String[]{"1"}));
     * </pre>
     *
     * @param <T>   给定数组元素类型。
     * @param array 给定的数组数组。
     * @return 真（true）表示给定的数组为非空。
     */
    public static <T> boolean isNotEmpty(T[] array) {
        return (null != array && array.length != 0);
    }

    /**
     * <pre>
     * 断言给定的对象是否为非空。
     * 如果给定的对象为null时则返回假（false）。
     * 如果给定的对象不为数组且不为null时则返回真（true）。
     * 如果给定的对象为数组且长度大于0时返回真（true），否则返回假（false）。
     * 例子：
     * assertTrue(ArrayUtils.isNotEmpty(""));
     * assertFalse(ArrayUtils.isNotEmpty((Object)new String[]{}));
     * assertTrue(ArrayUtils.isNotEmpty((Object)new String[]{"1"}));
     * </pre>
     *
     * @param obj 给定的对象。
     * @return 真（true）表示给定的对象为非空。
     */
    public static boolean isNotEmpty(Object obj) {
        return !isEmpty(obj);
    }

}
